package pl.poznan.put.cs.to.tsp;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import pl.poznan.put.cs.to.tsp.common.FileOperations;
import pl.poznan.put.cs.to.tsp.common.IResultHolder;
import pl.poznan.put.cs.to.tsp.common.Vertexes;
import pl.poznan.put.cs.to.tsp.heuristics.NormalHeuristic;
import pl.poznan.put.cs.to.tsp.listeners.EmptyTSPListener;
import pl.poznan.put.cs.to.tsp.listeners.GraphicWindow;
import pl.poznan.put.cs.to.tsp.listeners.TSPListener;
import pl.poznan.put.cs.to.tsp.listeners.TSPWindowListener;
import pl.poznan.put.cs.to.tsp.localsearch.LocalSearch;

public class MainApplication {
	private static Vertexes vertexes;

	private static String fileName;

	private static IResultHolder heuristic;

	private static GraphicWindow graphicWindow;

	private static TSPListener tspListener;
	private static TSPListener emptyTspListener;

	private static LocalSearch localSearch;

	public static final int MAX_TIME = 60000;

	public static void main(String[] args) {
		graphicWindow = new GraphicWindow();
		// tspListener = new TSPWindowListener(graphicWindow);
		tspListener = new TSPWindowListener(graphicWindow);
		emptyTspListener = new EmptyTSPListener();
		fileName = args[0];

		long sumOfTimes = 0;
		int sumOfResults = 0;
		int bestResult = Integer.MAX_VALUE;
		int tries = 10;
		List<Integer> values = new ArrayList<Integer>(tries);

		for (int i = 0; i < tries; i++) {
			vertexes = FileOperations.loadInstance(fileName);

			Calendar cal = Calendar.getInstance();
			long now = cal.getTimeInMillis();

			// try {
			heuristic = new NormalHeuristic(vertexes, emptyTspListener);
			LocalSearch ls = new LocalSearch(heuristic, emptyTspListener);
			IResultHolder rh = ls;
			cal = Calendar.getInstance();
			long after = cal.getTimeInMillis();
			tspListener.solutionGenerated(rh.getListA(), rh.getListB(), rh
					.getVertexes());
			int result = rh.getLengthA() + rh.getLengthB();
			sumOfResults += result;
			values.add(result);
			if (result < bestResult) {
				bestResult = result;
				// graphicWindow.paintSolution(ls.getListA(), ls.getListB(),
				// heuristic.getVertexes());
				// FileOperations.saveResultToFile(heuristic, "result.txt");
			}
			sumOfTimes += after - now;
		}
		double avg = sumOfResults / (double) tries;
		double var = 0;
		for (int v : values) {
			var += Math.abs(avg * avg - v * v);
		}
		var /= tries;
		System.out.println("Avg time: " + sumOfTimes / tries);
		System.out.println("Avg result: " + avg);
		System.out.println("Std dev result: " + Math.sqrt(var));
		System.out.println("Best result: " + bestResult);

		// FileOperations.saveResultToFile(heuristic, "result.txt");
		// heuristic.printResults();
		// System.out.println("Time of generating: " + (after - now));
	}
}
